/**
 *
 * @author 
 *
 */
class GroupLoad {
    private static _instance:GroupLoad;
    private groupGDic:GameDict = new GameDict();
    private groupLoading:boolean = false;
    
	public constructor() {
    	if(GroupLoad._instance){
            throw new Error("GroupLoad单例");
    	}
	}
	
	private initRegister():void{
        var self = GroupLoad._instance;
        RES.setMaxLoadingThread(5);
        RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE,self.onResourceLoadComplete,self);
        RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR,self.onResourceLoadError,self);
        RES.addEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR,self.onResourceLoadError,self);
        RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS,self.onResourceProgress,self);
	}
	
    private onResourceLoadComplete(event: RES.ResourceEvent):void{
        var self = this;
        if(event && event.groupName){
            var info:GroupLoadInfo = self.groupGDic.get(event.groupName);
            if(info && info.completeFun){
                info.completeFun.call(info.thisObject);
            }
            self.groupLoading = false;
            self.groupGDic.put(event.groupName,null);
            self.loadGroup();
        }
    }
    
    private loadGroup():void{
        var self = this;
        if(!self.groupLoading && self.groupGDic && self.groupGDic.length){
            var loadInfo = self.groupGDic.shift();
            if(RES.isGroupLoaded(loadInfo.groupName)){
                if(loadInfo.completeFun){
                    loadInfo.completeFun.call(loadInfo.thisObject);
                }
                self.loadGroup();
            }else{
                self.groupLoading = true;
                self.groupGDic.put(loadInfo.groupName,loadInfo);
                RES.loadGroup(loadInfo.groupName);    
                //LogManager.log("GroupLoad load:" + loadInfo.groupName);
            }
        }
    }
    
    private onResourceLoadError(event: RES.ResourceEvent):void{
        var self = this;
        self.groupLoading = false;
        self.loadGroup();
    }
    
    private onResourceProgress(event: RES.ResourceEvent):void{
        var self = this;
        var info:GroupLoadInfo = self.groupGDic.get(event.groupName);
        if(info && info.processFun){
            if(info.thisObject) {
                info.processFun.call(info.thisObject,event.itemsLoaded,event.itemsTotal);
            } else {
                info.processFun(event.itemsLoaded,event.itemsTotal);
            }
        }
    }
    
    private createGroupInfo(groupName,completeBack?: Function,processFun?:Function,thisObject?: any):GroupLoadInfo{
        var info: GroupLoadInfo = new GroupLoadInfo();
        info.groupName = groupName;
        info.completeFun = completeBack;
        info.processFun = processFun;
        info.thisObject = thisObject;
        return info;
    }
    
    public loadGroupByName(groupName,completeBack?:Function,processFun?:Function,thisObject?:any):void{
        var self = this;
        if(groupName){
            var info: GroupLoadInfo = self.createGroupInfo(groupName,completeBack,processFun,thisObject);
            self.groupGDic.put(info.groupName,info);
        }
        self.loadGroup();
    }
    
    public loadGroupList(groupList: Array<string>,completeBack?: Function,processFun?:Function,thisObject?: any):void{
        var self = this;
        var groupLen = groupList ? groupList.length : 0;
        for(var i:number = 0; i<groupLen; i++){
            var info:GroupLoadInfo = null;
            if(i == groupLen-1){
                info = self.createGroupInfo(groupList[i],completeBack,processFun,thisObject);
            }else{
                info = self.createGroupInfo(groupList[i]);
            }
            self.groupGDic.put(info.groupName,info);
        }
        self.loadGroup();
    }
	
	public static get instance():GroupLoad{
	    if(!GroupLoad._instance){
	        GroupLoad._instance = new GroupLoad();
            GroupLoad._instance.initRegister();
	    }
	    return GroupLoad._instance;
	}
}

class GroupLoadInfo{
    public groupName:string;
    public groupNameList:Array<string>;
    public completeFun:Function;
    public processFun:Function;
    public thisObject:any;
}
